#include <8052.h>

#include "ser.h"

#define NON_BLOCKING

unsigned char __xdata ser_txIndexIn;
unsigned char __xdata ser_txIndexOut;
unsigned char __xdata ser_rxIndexIn;
unsigned char __xdata ser_rxIndexOut;

unsigned char __xdata ser_txBuffer[0x100];
unsigned char __xdata ser_rxBuffer[0x100];

static __bit ser_txBusy;

void ser_init( void ) {
  ES = 0;
  ser_txBusy = 0;
  ser_txIndexIn = 0;
  ser_txIndexOut = 0;
  ser_rxIndexIn = 0;
  ser_rxIndexOut = 0;
  T2CON = 0x30;
  /* Baudrate = 19200, oscillator frq. of my processor is 21.4772 MHz */
  RCAP2H = 0xFF;
  RCAP2L = 0xDD;
  /* enable counter */
  T2CON = 0x34;
  SCON = 0x50;
  if( TI ) {
    TI = 0;
  }
  if( RI ) {
    RI = 0;
  }
  ES = 1;
}

void ser_interrupt_handler( void ) __interrupt 4 __using 1 {
  ES = 0;

  if( RI ) {
    RI = 0;
    ser_rxBuffer[ser_rxIndexIn++] = SBUF;
  }

  if( TI ) {
    TI = 0;
    if( ser_txIndexIn == ser_txIndexOut ) {
      ser_txBusy = 0;
    } else {
      SBUF = ser_txBuffer[ser_txIndexOut++];
    }
  }

  ES = 1;
}

void ser_putc( unsigned char c ) {
  ES = 0;
  if( ser_txBusy ) {
    ser_txBuffer[ser_txIndexIn++] = c;
  } else {
    ser_txBusy = 1;
    SBUF = c;
  }
  ES = 1;
}

unsigned char ser_getc( void ) {
  char tmp;
  #ifdef NON_BLOCKING
  if( ser_rxIndexIn != ser_rxIndexOut ) {
    tmp = ser_rxBuffer[ser_rxIndexOut++];
  } else {
    tmp = 0;
  }
  #endif
  return( tmp );
}

void ser_printString( char *String ) {
  while( *String ) {
    ser_putc( *String++ );
  }
}

char ser_charAvail( void ) {
  char ret = 0;
  if( ser_rxIndexIn != ser_rxIndexOut ) {
    ret = 1;
  }
  return( ret );
}
